/*
 * interrupt_avr8.h
 *
 *  Created on: Sep 13, 2013
 *      Author: Ken Arok
 */

#ifndef INTERRUPT_AVR8_H_
#define INTERRUPT_AVR8_H_

#include <compiler.h>
#include <parts.h>


#ifdef ISR_CUSTOM_H
#include ISR_CUSTOM_H
#else
#if defined(__DOXYGEN__)
#define ISR(vect)
#elif defined(__GNUC__)
#include <avr/interrupt.h>
#endif
#endif // ISR_CUSTOM_H

#if XMEGA
/**
 * \brief Initialize interrupt vectors
 * Enables all interrupt levels, with vectors located in the application section
 * and fixed priority scheduling.
 */
#define irq_initialize_vectors() \
	PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
#elif MEGA_RF
#define irq_initialize_vectors()
#endif

#ifdef __GNUC__
#define cpu_irq_enable()     sei()
#define cpu_irq_disable()    cli()
#else
#define cpu_irq_enable()     __enable_interrupt()
#define cpu_irq_disable()    __disable_interrupt()
#endif

typedef uint8_t irqflags_t;

static inline irqflags_t cpu_irq_save(void)
{
	irqflags_t flags = SREG;
	cpu_irq_disable();
	return flags;
}

static inline void cpu_irq_restore(irqflags_t flags)
{
	barrier();
	SREG = flags;
}

static inline bool cpu_irq_is_enabled_flags(irqflags_t flags)
{
#if XMEGA
#ifdef __GNUC__
	return flags & CPU_I_bm;
#else
	return flags & I_bm;
#endif
#elif MEGA || TINY
	return flags & (1 << SREG_I);
#endif
}

#define cpu_irq_is_enabled()             cpu_irq_is_enabled_flags(SREG)

// Deprecated definitions.
#define Enable_global_interrupt()        cpu_irq_enable()
#define Disable_global_interrupt()       cpu_irq_disable()
#define Is_global_interrupt_enabled()    cpu_irq_is_enabled()

#endif /* INTERRUPT_AVR8_H_ */
